

/*
 * This code is based on an example provided by Richard Stanford, 
 * a tutorial reader.
 */

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea;

import org.apache.xmlrpc.XmlRpcException;
import org.neos.client.NeosJobXml;
import org.neos.client.NeosXmlRpcClient;
import org.neos.client.ResultCallback;
import org.neos.client.ResultReceiver;

/**
 * Simple Java Swing application for submiting jobs to NEOS
 * @author Thawan Kooburat
 *
 */
public class MyPanel extends JPanel implements ActionListener,
		ResultCallback {

	private static final String SUBMIT_COMMAND = "submit";
	private static final String CLEAR_COMMAND = "clear";

	private static final String HOST = "www.neos-server.org";
	private static final String PORT = "3332";

	private JTextArea outputTextArea;
	private JButton submitButton;
	private JButton clearButton;
	private NeosXmlRpcClient client;
	private ResultReceiver reciever;

	public MyPanel() {
		super(new BorderLayout());

		JButton submitButton = new JButton("Submit");
		submitButton.setActionCommand(SUBMIT_COMMAND);
		submitButton.addActionListener(this);

		JButton clearButton = new JButton("Clear");
		clearButton.setActionCommand(CLEAR_COMMAND);
		clearButton.addActionListener(this);

		outputTextArea = new JTextArea(20, 20);
		outputTextArea.setEditable(false);
		outputTextArea.setText("init");
		// Lay everything out.

		JPanel buttonPanel = new JPanel(new GridLayout(1, 2));
		// buttonPanel.setPreferredSize(new Dimension(200, 30));
		buttonPanel.add(submitButton);
		buttonPanel.add(clearButton);
		add(buttonPanel, BorderLayout.NORTH);

		JPanel outputPanel = new JPanel(new FlowLayout());
		// outputPanel.setPreferredSize(new Dimension(200, 120));
		outputPanel.add(outputTextArea);
		add(outputPanel, BorderLayout.CENTER);

		setSize(new Dimension(300, 200));

		client = new NeosXmlRpcClient(HOST, PORT);

		try {
			client.connect();
		} catch (XmlRpcException e) {
			outputTextArea.setText("Unable to connect to NEOS server :"
					+ e.getMessage());
		}
	}

	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();

		if (command.equals(SUBMIT_COMMAND)) {
			submitJob();

		} else if (command.equals(CLEAR_COMMAND)) {
			outputTextArea.setText("");
			System.out.println("clear");
			System.out.println(reciever.getResult());
		}
	}

	public void submitJob() {
		
		String gmscode = "$title Final Project Parking Lot\noption optcr=0.0;\nfree variable Z;\n*Start parkinglots\nset N \"Nodes(src lots)\" / L0*L5 /;\nset P(N) \"parking lots\";\nP(N) = yes;\nP(\'L0\') = no;\n\n\nparameter w1,w2,w3,npts;\n* w1 for fee, w2 for driving dist, w3 for walking dist\nw1 = 1;\nw2 = 1;\nw3 = 1;\n* n candidates\nnpts = 3;\n\nalias(N,i,j);\nparameter F(N);\nF(i) = round(10*uniform(2,5)+5);\nparameter D(i,j);\nD(i,j) = round(10*uniform(2,5));\nparameters W(N);\nW(P) = round(3*uniform(2,5));\n\n\nset Arc(N,N);\nArc(i,j) = yes;\n\nbinary variable Y(N);\nbinary variable X(N,N);\nnonnegative variable R(N,N);\nfree variable S(N);\nequations\n         obj\n         nLots\n         startpts\n         balance(N)\n         cons1(N)\n         cons2(N)\n         cons3(N)\n         cons4(N)\n         cons5(N,N)\n         cons6(N,N)\n         cons7(N)\n         cons8\n;\n\nobj..\nZ =e= w1*sum(P,F(P)*Y(P)) + w2*sum((i,j)$Arc(i,j),D(i,j)*R(i,j))+w3*sum(P,W(P)*Y(P));\n\nnLots..\nsum(P,Y(P)) =e= npts;\n\nstartpts..\nY(\'L0\') =e= 1;\n\nbalance(i)..\nsum(j$Arc(j,i),R(j,i))+S(i) =e= sum(j$Arc(i,j),R(i,j));\n\ncons1(i)..\nsum(j$Arc(i,j),X(i,j)) =l= 1;\n\ncons2(i)..\nsum(j$Arc(j,i),X(j,i)) =l= 1;\n\ncons3(i)..\nY(i) =g= (sum(j$Arc(i,j),X(i,j))+sum(j$Arc(j,i),X(j,i)))/2;\n\ncons4(i)..\nY(i) =l= (sum(j$Arc(i,j),X(i,j))+sum(j$Arc(j,i),X(j,i)));\n\ncons5(i,j)..\nR(i,j)/npts =l= X(i,j);\n\ncons6(i,j)..\nR(i,j) =g= X(i,j);\n\ncons7(i)$(ord(i) gt 2)..\nS(i) =e= -1*Y(i);\n\ncons8..\nS(\'L0\') =e= npts;\n\nmodel hw /\n         obj\n         nLots\n         startpts\n         balance\n         cons1\n         cons2\n         cons3\n         cons4\n         cons5\n         cons6\n         cons7\n         cons8\n/;\nsolve hw using mip minimizing Z ;\noption X:0:0:1 ;\noption Y:0:0:1 ;\noption R:0:0:1 ;\noption S:0:0:1 ;\ndisplay X.l,Y.l,R.l,S.l;\n";
		NeosJobXml job = new NeosJobXml("milp", "Gurobi", "GAMS");
		job.addParam("model", gmscode);
		
		Vector params = new Vector();
		// Job xml
		params.add(job.toXMLString());
		
		Integer currentJob = 0;
		String currentPassword = "";

		try {
			Object[] results = (Object[]) client.execute("submitJob", params);

			currentJob = (Integer) results[0];
			currentPassword = (String) results[1];
		} catch (XmlRpcException e) {
			outputTextArea.setText("Error submitting job :" + e.getMessage());
			return;
		}
		if (currentJob == 0) {
			System.out.println(currentPassword);
			return;
		}
		reciever = new ResultReceiver(client, this, currentJob, currentPassword);
		reciever.start();
		


	}

	@Override
	public void handleJobInfo(int jobNo, String pass) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void handleFinalResult(String results) {
		outputTextArea.setText(results);

	}

	

	
}
